use bus_trait::Business;
use serde::de::{self, Visitor};
use std::{
	fmt::{self, Debug},
	result,
};
use tracing::error;

use crate::config::business_config;

pub mod bus_trait;
pub mod called_rule;
pub mod calling_card;
pub mod dial_test_server;
pub mod extra;
pub mod fs_register;
pub mod inbound400;
pub mod outbound;

pub trait RunContext {
	fn take_next_handler(&mut self) -> Option<&'static dyn Business<C = Self>>;
}

///号码呼叫类型,目前分为内部和外部两种.分别走不同通道呼出
#[derive(Debug, PartialEq, Eq, Clone,Copy)]
#[repr(i32)]
pub enum TurnnumCallType {
	///通过运营商的网关进行呼叫
	CallWithIsp,
	///通过对接的外部网关进行呼叫
	CallExGW,
	///直接向某一个已经注册的终端进行呼叫
	CallTerminal,
	///未知
	Unknow,
}

impl Default for TurnnumCallType {
	fn default() -> Self {
		TurnnumCallType::Unknow
	}
}

#[derive(Debug, PartialEq, Eq)]
pub enum ISP {
	ChinaTelecom,
	ChinaUnicom,
	ChinaMobile,
	Other,
}

impl From<&str> for ISP {
	fn from(value: &str) -> Self {
		match value {
			"中国电信" => ISP::ChinaTelecom,
			"中国联通" => ISP::ChinaUnicom,
			"中国移动" => ISP::ChinaMobile,
			_ => ISP::Other,
		}
	}
}

impl<'de> serde::Deserialize<'de> for ISP {
	fn deserialize<D>(deserializer: D) -> std::prelude::v1::Result<Self, D::Error>
	where
		D: serde::Deserializer<'de>,
	{
		struct ISPVisitor;

		impl<'de> Visitor<'de> for ISPVisitor {
			type Value = ISP;

			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
				formatter.write_str("错误")
			}

			fn visit_str<E>(self, value: &str) -> result::Result<ISP, E>
			where
				E: de::Error,
			{
				Ok(value.into())
			}
		}

		deserializer.deserialize_str(ISPVisitor)
	}
}

///节点信息的结构
#[derive(Debug, Clone)]
pub struct NodeInfo {
	// ///上级id
	pub parent_id: i32,
	///本级要收到按键的长度
	pub under_key_len: i32,
	///进入本级的对应按键
	pub dtfm: String,
	///彩铃路径
	pub conn_begin_bell_path: String,
	pub flag: i32,
	pub node_id: i32,
	///是否立即接通
	pub immconnect: bool,
	pub node_type: NodeType,
	pub turn_nums: Vec<TurnNumInfo>,
}

impl NodeInfo {
	pub fn with_type(node_type: NodeType) -> Self {
		Self {
			node_type,
			..Default::default()
		}
	}
}

impl Default for NodeInfo {
	fn default() -> Self {
		Self {
			under_key_len: 0,
			dtfm: Default::default(),
			conn_begin_bell_path: Default::default(),
			flag: -1,
			node_id: -1,
			immconnect: false,
			node_type: NodeType::Call,
			turn_nums: Vec::with_capacity(10),
			parent_id: 0,
		}
	}
}

///实际的向外呼叫号码信息
#[derive(Debug, Clone, Default)]
pub struct TurnNumInfo {
	pub num: String,
	pub wait_seconds: i32,
	pub _flag: i32,
	pub _job_num: String,
	pub _id: i32,
	pub node_id: i32,
	pub call_type: TurnnumCallType,
}

impl TurnNumInfo {
	pub fn new(
		num: String,
		wait_seconds: i32,
		node_id: i32,
		call_type:TurnnumCallType
	) -> Self {
		Self {
			num,
			wait_seconds,
			node_id,
			call_type,
			..Default::default()
		}
	}
}

#[derive(Debug, Clone)]
#[repr(i32)]
pub enum NodeType {
	IVR,
	Call,
}

impl From<result::Result<i32, sqlx::Error>> for NodeType {
	fn from(value: result::Result<i32, sqlx::Error>) -> Self {
		//根据不同的i32的值.这里针对性的进行转换.
		match value {
			Ok(v) if v & NodeType::Call as i32 != 0 => Self::Call,
			Ok(v) if v & NodeType::IVR as i32 != 0 => Self::IVR,
			Ok(_) => Self::Call,
			Err(e) => {
				error!("获取数据出现异常:{}", e);
				Self::Call
			}
		}
	}
}


#[derive(Debug)]
pub enum CallerSendRule<'a> {
	///使用原主叫号码
	SourceCaller,
	///使用目的码
	Target,
	///使用指定号码
	Specified(&'a str),
}

impl From<u8> for CallerSendRule<'_> {
	fn from(value: u8) -> Self {
		match value {
			1 => CallerSendRule::SourceCaller,
			2 => CallerSendRule::Target,
			3 => CallerSendRule::Specified(business_config().specific_caller_num),
			_ => CallerSendRule::SourceCaller,
		}
	}
}